﻿using System;
using System.Collections.Generic;
using Castle.Services.Transaction;
using Evolus.Mercury.Exceptions;
using Evolus.Mercury.Model;
using Evolus.Mercury.Specifications;
using Hippo.Core.Data;

namespace Evolus.Mercury
{
    [Transactional]
    public class MarketService : IMarketService
    {
        IRepository repository;

        public MarketService(IRepository repository)
        {
            this.repository = repository;
        }

        public void AddMarket(Market market)
        {
            repository.Create<Market>(market);
        }

        public Market GetMarket(string code)
        {
            Market market = repository.FindFirst(new MarketHasCodeSpecification(code));
            if (market == null)
            {
                throw new MarketNotFoundException(code);
            }
            return market;
        }

        [Castle.Services.Transaction.Transaction(TransactionMode.Requires)]
        public void AddStock(Stock stock)
        {
            throw new NotImplementedException();
        }

        [Castle.Services.Transaction.Transaction(TransactionMode.Requires)]
        public void UpdateStocks(IList<StockInfo> stocks)
        {
            foreach (StockInfo stockInfo in stocks)
            {
                StockInfo currentInfo = repository.FindFirst(new StockInfoOfDateSpecification(stockInfo.Stock.Symbol, stockInfo.Date));
                if (currentInfo != null)
                {
                    bool changed = currentInfo.UpdateWith(stockInfo);
                    if (changed)
                    {
                        currentInfo.LastUpdatedTime = DateTime.Now;
                        repository.Update(currentInfo);
                    }
                }
                else
                {
                    StockHasSymbolSpecification spec = new StockHasSymbolSpecification(stockInfo.Stock.Symbol);
                    Stock stock = repository.FindFirst(spec);
                    if (stock == null)
                    {
                        repository.Create(stockInfo.Stock);
                        stockInfo.Stock = repository.FindFirst(spec);
                    }
                    else
                    {
                        stockInfo.Stock = stock;
                    }
                    stockInfo.LastUpdatedTime = DateTime.Now;
                    repository.Create(stockInfo);
                }
            }
        }

        public IList<StockInfo> GetChanges(string[] symbols, DateTime lastUpdatedTime)
        {
            return repository.FindBySpecification(new ChangedSinceSpecification(symbols, lastUpdatedTime));
        }        
    }
}
